﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Linq.Expressions;
using CH.Easy.DbProvider.Interface;

namespace CH.Easy.DbProvider.Core
{
    public class Specification<T>
    {
        private Expression<Func<T, bool>> where;
        public Specification()
        {

        }
        public Expression<Func<T, bool>> Sp
        {
            get
            {
                if (this.where == null)
                {
                    this.where = (p) => 1 > 0;
                }
                return this.where;
            }
        }
     
        public Specification<T> And(Expression<Func<T, bool>> exp)
        {
            if (where == null)
            {
                this.where = exp;
            }
            else
            {
                //1、这种写法可以创建表达式树 但是不能创建表达式树委托执行
                this.where = Expression.Lambda<Func<T, bool>>(Expression.And(this.where.Body, exp.Body), this.where.Parameters);


                //2、这种写法可以创建表达式树 可以创建表达式树委托执行
                //this.where = Expression.Lambda<Func<T, bool>>(Expression.And(this.where.Body, Expression.Invoke(exp, this.where.Parameters.Cast<Expression>())), this.where.Parameters);


                //3、这种写法可以创建表达式树 可以创建表达式树委托执行
                //Expression.Invoke(exp, this.where.Parameters.Cast<Expression>()) 调用一个委托
                //this.where.Parameters.Cast<Expression>() 是要传入的参数
                //var andExp = Expression.And(Expression.Invoke(this.where, this.where.Parameters), Expression.Invoke(exp, this.where.Parameters));
                //this.where = Expression.Lambda<Func<T, bool>>(andExp, this.where.Parameters);
            }
            return this;
        }
        public Specification<T> Or(Expression<Func<T, bool>> exp)
        {

            if (where == null)
            {
                this.where = exp;
            }
            else
            {


                //1、这种写法可以创建表达式树 但是不能创建表达式树委托执行
                this.where = Expression.Lambda<Func<T, bool>>(Expression.Or(this.where.Body, exp.Body), this.where.Parameters);


                //2、这种写法可以创建表达式树 可以创建表达式树委托执行
                //this.where = Expression.Lambda<Func<T, bool>>(Expression.Or(this.where.Body, Expression.Invoke(exp, this.where.Parameters.Cast<Expression>())), this.where.Parameters);


                //3、这种写法可以创建表达式树 可以创建表达式树委托执行
                //Expression.Invoke(exp, this.where.Parameters.Cast<Expression>()) 调用一个委托
                //this.where.Parameters.Cast<Expression>() 是要传入的参数
                //var andExp = Expression.Or(Expression.Invoke(this.where,this.where.Parameters), Expression.Invoke(exp, this.where.Parameters));
                //this.where = Expression.Lambda<Func<T, bool>>(andExp, this.where.Parameters);






            }
            return this;
        }








    }
}
